home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1998 May / EnigmA AMIGA RUN 27 (1998)(G.R. Edizioni)(IT)[!][issue 1998-05].iso / recent1 / gifani.lha / gifanim_datatype / classbase.c < prev    next >
C/C++ Source or Header  |  1998-04-13  |  26KB  |  704 lines

  1.  
  2. /*
  3. **
  4. **  $VER: classbase.c 2.2 (13.4.98)
  5. **  gifanim.datatype 2.2
  6. **
  7. **  Library routines for a DataTypes class
  8. **
  9. **  Written 1997/1998 by Roland 'Gizzy' Mainz
  10. **  Original example source from David N. Junod
  11. **
  12. */
  13.  
  14.  
  15. /* main includes */
  16. #include "classbase.h"
  17.  
  18.  
  19. /****** gifanim.datatype/MAIN ************************************************
  20. *
  21. *    INTRODUCTION
  22. *        Datatypes class for GIF animations. Based on "giftopnm" by David
  23. *        Koblas, "ppmtogif" by Marcel Wijkstra <wijkstra@fwi.uva.nl> and
  24. *        David Rowley <mgardi@watdscu.waterloo.edu> and the CBM datatypes 
  25. *        example source/ documents written by David Junod.
  26. *
  27. *    LEGAL
  28. *      * Note that this implementation uses LZW, which is PATENTED by UniSys
  29. *        in the U.S.A.
  30. *
  31. *        Therefore, this application must not be used inside the United
  32. *        States of America except for research purposes.
  33. *
  34. *      - Compuserves banner:
  35. *
  36. *      "The Graphics Interchange Format(c) is the Copyright property of
  37. *      CompuServe Incorporated. GIF(sm) is a Service Mark property of
  38. *      CompuServe Incorporated."
  39. *
  40. *      - "giftopnm" legal info:
  41. *      +-------------------------------------------------------------------+
  42. *      | Copyright 1990, 1991, 1993, David Koblas.  (koblas@netcom.com)    |
  43. *      |   Permission to use, copy, modify, and distribute this software   |
  44. *      |   and its documentation for any purpose and without fee is hereby |
  45. *      |   granted, provided that the above copyright notice appear in all |
  46. *      |   copies and that both that copyright notice and this permission  |
  47. *      |   notice appear in supporting documentation.  This software is    |
  48. *      |   provided "as is" without express or implied warranty.           |
  49. *      +-------------------------------------------------------------------+
  50. *
  51. *    REQUIREMENTS
  52. *        - You need at least Kick/WB 3.0.
  53. *          | Many people wrote me that they cannot find an
  54. *          | "animation.datatype" class.
  55. *          | Only the 3.1 release contains it. (Subclasses of)
  56. *          | animation.datatype can run under 3.0.
  57. *
  58. *        - "datatypes/animation.datatype", >= V41
  59. *          "animation.datatype V41" requires itself some
  60. *          libraries/boopsi classes:
  61. *        - "realtime.library", >= V39              - for timing
  62. *        - "gadgets/tapedeck.gadget" (any version) - for the controls
  63. *
  64. *           If you want to attach samples, you need "sound.datatype" >= V39
  65. *           and your prefereed subclass (8svx.datatype for IFF 8SVX samples
  66. *           etc.).
  67. *
  68. *    USAGE
  69. *        If the datatypes descriptor file was activated, any attempt to load
  70. *        a GIF anim stream using GMultiView, MultiView, AmigaGuide or
  71. *        SwitchWindow will load and play the animation. If the source was a
  72. *        file, gifanim.datatype loads frames dynamically from disk.
  73. *
  74. *        If you want to save the current animation in gifanim.datatype's
  75. *        local format, use MultiView's "Project/Save As..." menu (or
  76. *        GMultiView's "Project/Save As Raw...").
  77. *        gifanim.datatype saves the current animation, starting with the
  78. *        current frame as GIF animation.
  79. *
  80. *        If you want to attach samples to the animation, you must edit the
  81. *        prefs file (ENV:Classes/DataTypes/gifanim.prefs) and add the
  82. *        following line:
  83. *        VERBOSE SAMPLE="ram:have_a_nice_day.8svx"
  84. *        Which loads and attaches the sample "ram:have_a_nice_day.8svx" to
  85. *        the animation. See gifanim.datatype.doc/preferences for a complete
  86. *        description of the prefs file.
  87. *
  88. *    INSTALLATION
  89. *        After unpacking this archive:
  90. *        Because this version does not include an Installer script, you have
  91. *        to do the installation manually through the shell:
  92. *
  93. *          - Unpack this archive and copy the "gifanim.datatype" to
  94. *            SYS:Classes/DataTypes/:
  95. *
  96. *        Copy CLONE FROM "gifanim.datatype" TO
  97. *         "SYS:Classes/DataTypes/gifanim.datatype"
  98. *
  99. *          - Then copy the datatypes descriptor into the DEVS:DataTypes
  100. *            directory.
  101. *            If the descriptor already exists, you should not replace it,
  102. *            otherwise you may loose "toolnodes" and other settings stored in
  103. *            the existing descriptor.
  104. *
  105. *     Copy CLONE FROM "GIFANIM(%|.info)" TO DEVS:Datatypes/
  106. *
  107. *    SOURCE
  108. *        Source is included as an example how to write an
  109. *        animation.datatype subclass which deals with things chunky bitmaps
  110. *        deltas and an encoder...
  111. *
  112. *    AUTHOR
  113. *        If you want to blame me, report any bugs, or wants a new version
  114. *        send your letter to:
  115. *                        Roland Mainz
  116. *                        Hohenstaufenstraße 8
  117. *                        52388 Nörvenich
  118. *                        GERMANY
  119. *
  120. *        Phone: (+49)(0)2426/901568
  121. *        Fax:   (+49)(0)2426/901569
  122. *
  123. *        EMAIL is also available (if you want to send me attachments
  124. *        larger than 1MB (up to 5MB, more with my permission):
  125. *
  126. *        GISBURN@w-specht.rhein-ruhr.de
  127. *
  128. *        Up to May 1998 I'm reachable using this email address, too:
  129. *        Reinhold.A.Mainz@KBV.DE
  130. *
  131. *        | Please put your name and address in your mails !
  132. *        | German mailers should add their phone numbers.
  133. *        | See BUGS section above when submitting bug reports.
  134. *
  135. *        Sorry, but I can only look once a week for mails.
  136. *        If you don't hear something from me within three weeks, please
  137. *        send your mail again (but watch about new releases) (problems with
  138. *        this email port are caused by reconfigurations, hackers, network
  139. *        problems etc.).
  140. *
  141. *        The  entire  "gifanim.datatype"  package  may  be  noncommercially
  142. *        redistributed, provided  that  the package  is always  distributed
  143. *        in it's complete  form (including it's documentation). A small
  144. *        copy fee  for media costs is okay but any kind of commercial
  145. *        distribution is strictly forbidden without my permission !
  146. *        Comments and suggestions how to improve this program are
  147. *        generally appreciated!
  148. *
  149. *        Thanks to David Junod, who wrote the animation.datatype and lots of
  150. *        the datatypes example code, David Koblas for his "giftopnm"
  151. *        and other people for their compression formats, Peter McGavin for
  152. *        his C2P function, Matt Dillon for his DICE, Olaf 'Olsen' Barthel
  153. *        for his help, ideas and some text clips from his documentations.
  154. *
  155. ******************************************************************************
  156. *
  157. */
  158.  
  159.  
  160.  
  161. /****** gifanim.datatype/--datasheed-- ***************************************
  162. *
  163. *   NAME
  164. *       gifanim.datatype -- data type for GIF Animations
  165. *
  166. *   SUPERCLASS
  167. *       animation.datatype
  168. *
  169. *   DESCRIPTION
  170. *       The anim datatype, a sub-class of the animation.datatype, is used to
  171. *       load, play and encode (save) GIF animations.
  172. *       It supports GIF 87a and GIF 89a compressed animations.
  173. *       Using the prefs-file, any sound can be attached to the animation.
  174. *
  175. *   METHODS
  176. *       OM_NEW -- Create a new animation object from a description file. The
  177. *           source may only be a file. Or an empty object can be created for 
  178. *           encoding (which must be filled by the application before 
  179. *           encoding).
  180. *
  181. *       OM_DISPOSE -- Dispose instance and contents (frames, colormaps, sounds
  182. *           etc.), then pass msg to superclass
  183. *
  184. *       OM_UPDATE -- Perform an ICM_CHECKLOOP check, and if succesfull, the
  185. *           method will be executed like OM_SET downstairs.
  186. *
  187. *       OM_SET -- Pass msg to superclass and call GM_RENDER if retval from
  188. *           superclass was != 0UL.
  189. *
  190. *       DTM_WRITE -- Save object's contents in local (GIF Animation) or
  191. *           superclass (IFF ILBM) format.
  192. *
  193. *       ADTM_LOADFRAME -- Fill in struct adtFrame with requested information
  194. *           from internal FrameNode list like bitmap, colormap and sample. If
  195. *           the bitmap information is not loaded yet, it will be loaded from
  196. *           disk.
  197. *
  198. *       ADTM_UNLOADFRAME -- Free resources obtained by ADTM_UNLOADFRAME.
  199. *
  200. *       All other methods are passed unchanged to superclass.
  201. *
  202. *   ATTRIBUTES
  203. *       Following attributes are set by the object and are READ-ONLY for
  204. *       applications:
  205. *       DTA_ObjName             - file name
  206. *       DTA_ObjAnnotation       - set by extension blocks (gif 89a comment
  207. *                                 extention)
  208. *       DTA_TotalHoriz          - same as ADTA_Width
  209. *       DTA_TotalVert           - same as ADTA_Height
  210. *       ADTA_Width              - set by GIF screen
  211. *       ADTA_Height             - set by GIF screen
  212. *       ADTA_Depth              - set by GIF screen
  213. *       ADTA_Frames             - number of frames in animation
  214. *       ADTA_FramesPerSecond    - fixed to 100 fps
  215. *       ADTA_ModeID             - mode id flags
  216. *       ADTA_KeyFrame           - Key frame of animation
  217. *
  218. *       The following attributes are only set if a sample is attached using 
  219. *       the prefs-file:
  220. *       ADTA_Sample             - only set to notify the anmation.datatype
  221. *                                 instance that the object has sound data
  222. *       ADTA_SampleLength       - size of sample data played within one 
  223. *                                 timestamp
  224. *       ADTA_Period             - sample period
  225. *       ADTA_Volume             - volume as set by the prefs-file
  226. *
  227. *   BUGS
  228. *       * The whole code looks like a big hack; sorry, but this datatype was
  229. *         put together within 2 hours...
  230. *         ...V1.2 only fixes some bugs and adds a few features.
  231. *         ...V1.3 fixed some things, adds some legal stuff and CyberGFX
  232. *            support
  233. *
  234. *       - Does not support transparency yet (the encoder supports 
  235. *         transparency througth a prefs-option).
  236. *
  237. *       - Very slow playback.
  238. *         Reasons:
  239. *         - Multiple memory allocations, Seek's and Read's in one
  240. *           ADTM_LOADFRAME
  241. *         - Unbufferd loading
  242. *         - C2P conversion (fast, but not the fastest possible)
  243. *         - crap design
  244. *         - Slow gif decoder. Rewriting the beast in ASM maybe speed up
  245. *           things, but I don't know much about m68k assember.
  246. *           Anybody out there who wants to do the job ?
  247. *         ....
  248. *
  249. *         To get rid of this problem, the LOADALL switch is set for now.
  250. *         On >= mc68040/40MHz, the LOADALL switch in unneccesary, use
  251. *         NOLOADALL in this case...
  252. *
  253. *       - Some anims get a trashed background, maybe due a bug in the GIF89a
  254. *         frame disposal support code.
  255. *         Any hint/example animation ?
  256. *
  257. *       - This datatype was written for animation.datatype V41. Using this
  258. *         datatype with animation.datatype V40.6 does not work !
  259. *         Not a bug, but...
  260. *
  261. *       - In large videos, the frames at the end will be played slower than
  262. *         those at the beginning of the file. This is the result of the
  263. *         sequential search internally used (only serious with more than 25000
  264. *         frames (mc6030/50mhz)).
  265. *         May or may not be fixed.
  266. *
  267. *       - CyberGFX support is still under development. It seems that it works
  268. *         good, but...
  269. *
  270. *       - CyberGFX C2C conversion (LUT8 -> RGB16/24) uses a very crap method
  271. *         througth WriteRGBPixel...
  272. *
  273. *   TODO
  274. *       - Fixing the bugs above.
  275. *
  276. *       - Write the "--input_format--"-Autodoc section.
  277. *
  278. *   HISTORY
  279. *       V1.1
  280. *         Released to the Waldspecht-BBS for testing.
  281. *
  282. *       V1.2
  283. *         - Found and fixed the longstanding bug that animation.datatype
  284. *           V40.7 didn't free some frames. Reason is that ADTM_LOADFRAME
  285. *           may be used like "realloc". Now alf_UserData is checked;
  286. *           any given frame will be freed (ADTM_UNLOADFRAME).
  287. *           Fixed.
  288. *
  289. *         - Minor houskeeping changes; removed some unneccesary code.
  290. *
  291. *         - Now uses buffered reading (FRead instead of Read and SetVBuf).
  292. *           Maybe this speeds up loading a little bit.
  293. *
  294. *         - Fixed the bug in NOLOADALL loading mode (dynamic loading of
  295. *           frames from disk) that some "disposal" modes (previous image)
  296. *           didn't work properly under some conditions.
  297. *           Fixed.
  298. *
  299. *         - Fixed the bug that animations with a static background were
  300. *           not correctly handled in LOADALL mode (I simply forgot
  301. *           to write the code...).
  302. *           Thanks to Francis Labrie (fb691875@er.uquam.ca) for reporting
  303. *           the bug.
  304. *           Fixed.
  305. *
  306. *         - Fixed the bug that ADTM_LOADFRAME returns evertimes
  307. *           ERROR_NO_FREE_STORE on failure instead of returning the real
  308. *           cause.
  309. *           Also fixed the error handling code in ADTM_LOADFRAME.
  310. *           Fixed.
  311. *
  312. *         - Implemented a delta mode for WPA8. If possible (e.g. if the
  313. *           current frame uses the previous one as it's background), only
  314. *           the changed areas are processed by the C2P code.
  315. *
  316. *         - Now supports the GIF comment extension. The character set is
  317. *           converted automatically, chars > 128 are replaced by '_'
  318. *           except the german 'ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü' and 'ß'.
  319. *           Multiple comment chunks are merged together.
  320. *           The comment will be stored in DTA_ObjAnnotation.
  321. *
  322. *         - Cut some unneccesary VERBOSE output.
  323. *
  324. *       V1.3
  325. *         | Internal testing release to search for the mysterious memory loss
  326. *         | in conjunction with the 24BITCHUNKY option.
  327. *
  328. *         - Added the notice that UniSys holds the LZW patents in the USA.
  329. *
  330. *         - Removed BestModeIDA, because animation.datatype does the same
  331. *           thing.
  332. *
  333. *         - Small code cleanup.
  334. *           Removed some of the debugging code and removed some parts of
  335. *           dead code.
  336. *
  337. *         - Fixed the "maximum timestamp" (ADTA_Frames) calculation.
  338. *           the old way was very crap...
  339. *           Fixed.
  340. *
  341. *         - Added some padding bytes in the decoder (instance data) part.
  342. *           Now the data are aligned, which should speed up the decoding.
  343. *
  344. *         - Fixed possible problems when a GIF "Comment Extension" text is
  345. *           not '\0'-terminated. Now the load buffer is zero'ed for each new
  346. *           cycle.
  347. *           Fixed.
  348. *
  349. *         - Added some VERBOSE about the "Plain Text Extension". The contents
  350. *           are now shown in the verbose output.
  351. *
  352. *         - Fixed the bug that in the case that the first frame has no bitmap
  353. *           a bitmap with 0,0,0 dimensions would be allocated.
  354. *           (Did not occur, but...)
  355. *           Fixed.
  356. *
  357. *         - Implemented a prefetch buffer for dynamic load mode (e.g.
  358. *           NOLOADALL); now all data needed for the frame are loaded with one
  359. *           Read statement, all following accesses are redirected to the
  360. *           filled buffer.
  361. *           Switched from FRead to Read again because we're now loading
  362. *           larger blocks.
  363. *
  364. *         - Fixed the width padding problem, which caused an ugly border
  365. *           filled with rubbish in some anims.
  366. *           Fixed.
  367. *
  368. *         - Now supports different disposal modes in one animation (each
  369. *           frame can have it's own disposal mode).
  370. *
  371. *         - Now supports different transarent colors in one animation (each
  372. *           frame can have it's own transparent color).
  373. *
  374. *         - Removed all references to ADTA_BitMapHeader. It's not required
  375. *           for this format.
  376. *
  377. *         - Now saves the transparent color values from the previous colormap.
  378. *
  379. *         - Fixed the bug that the datatypes creates everytimes a
  380. *           palette-per-frame instead of creating them only if neccesary.
  381. *           Fixed.
  382. *
  383. *         - Now sets the GIF Screen background color to 0 if there is no
  384. *           global colormap.
  385. *
  386. *         - Added CyberGFX-Support. Upon request, the datatype tries to create
  387. *           a 24-bit chunky bitmap if the 24BITCHUNKY prefs switch is set.
  388. *           WARNING: Does only work with animation.datatype V41 or higher
  389. *           (<= V41.2 had a small bug which has been fixed in V41.3).
  390. *
  391. *         - Added CyberGFX bug workaround when BestCModeIDA fails when the
  392. *           dimensions given are too small (e.g. 32 * 50 returns INVALID_ID).
  393. *           Then 640 * 480 are set.
  394. *           Not very nice.
  395. *
  396. *         - Added GIF Picture descriptor to replace any version with a wrong
  397. *           mask.
  398. *
  399. *       V1.4
  400. *         - Very much thanks to Frank Mariak (fmariak@chaosengine.ping.de)
  401. *           for finding the silly "too big palette"-bug in conjunction
  402. *           with the new chunkypixel output.
  403. *
  404. *       V1.5
  405. *         - Major code cleanup. BOOPSI class structures have been moved
  406. *           to classdata.h, class independed functions have been moved
  407. *           into misc.c, class preferences to prefs.c
  408. *
  409. *         - Replaced the custom stackswapping code with my "standard"
  410. *           module "stackswap.c".
  411. *
  412. *         - OM_DISPOSE now preserves Result2 (IoErr()).
  413. *
  414. *         - Fixed the longstandig bug in ScanFrames that if an OS function
  415. *           failed, and IoErr results 0, havoc broke out.
  416. *           Fixed.
  417. *
  418. *         - ADTA_SampleLength calculations were wrong. The value was got
  419. *           from the first frame. Now the value is set correctly to
  420. *           alf_SampleLength / (alf_Duration + 1)
  421. *           Fixed.
  422. *
  423. *         - If a ADTM_LOADFRAME method gets a message from a previous
  424. *           ADTM_LOADFRAME call, the contents are freed now after
  425. *           the requested data have been loaded. This avoids the
  426. *           pathological case that if the same frame should be freed and
  427. *           returned the frame IS freed and then re-loaded.
  428. *           Now the free of the given frame is done after the loading
  429. *           of the requested frame which avoids this inefficienty.
  430. *           Fixed.
  431. *
  432. *         - Switched truecolor output down to 16 bit (565-bits-per-gun)
  433. *           to save some mem...
  434. *
  435. *         - Added 16BITCHUNKY, NO16BITCHUNKY, TRUECOLOR and NOTRUECOLOR
  436. *           options.
  437. *
  438. *         - Fixed ModeID handling. The previous behaviour was that
  439. *           a 0 mode id causes the datatype to select it's own mode id.
  440. *           But 0 means LORES. Now the default is -1 (which means
  441. +           INVALID_ID), which causes the datatype to do it's own
  442. *           calculations.
  443. *           Fixed.
  444. *
  445. *       V2.1
  446. *         - Implemeted the GIF animation encoder part.
  447. *           The encoder writes GIF89a animation streams out.
  448. *
  449. *         - Fixed a mask bug in the suppied "GIF" descriptor;
  450. *           a byte after the "GIF" signature was set to match,
  451. *           Fixed.
  452. *
  453. *         - gifanim.datatype now requires at least animation.datatype V41
  454. *           as base class.
  455. *           (mainly to get rid of the V40 workround code which tried to
  456. *           get class working with animation.datatype V40).
  457. *
  458. *         - Updated and cleaned-up the autodoc a little bit.
  459. *
  460. *       V2.2
  461. *         - Minor code cleanup
  462. *
  463. *         - Removed REPEAT and NOREPEAT options/feature because this
  464. *           hack-like "feature" seems to be incompatible to GMultiView's
  465. *           repeat option.
  466. *           Problem fixed.
  467. *
  468. *         - Added encoder prefs options to set GIF interlace mode, transparent
  469. *           and background pens.
  470. *           See "gifanim.datatype.doc" section "preferences" for details.
  471. *           Currently untested...
  472. *
  473. *         - Major speedup in the encoder part (~ three times faster).
  474. *           a) The encoder now writes any incoming bitmap in an chunkypixel
  475. *              array and operates on it instead of doing ReadPixel for
  476. *              each pixel.
  477. *           b) Minor other changes in the encoder section...
  478. *
  479. *         - The decoder now treats 0x00-chars in the chunk id position as 
  480. *           padding bytes and does not prompt any sytax error any more.
  481. *           Now the "slidbar.gif" created by "GifBuilder 0.2" works...
  482. *
  483. *         - Introduced the option STRICTSYNTAX which prints additionally 
  484. *           syntax errors (like the 0x00 padding bytes above...).
  485. *
  486. *         - Added Installation script "Install DataType". 
  487. *           It would be very nice if someone has the time to write a
  488. *           1:1 CBM Installer version of it...
  489. *
  490. *
  491. *   NOTES
  492. *       This datatype first scans the whole animation to get index
  493. *       information (if the LOADALL switch was set in the prefs-file,
  494. *       the entire animation will be loaded), colormaps will be loaded
  495. *       immediately.
  496. *
  497. *   SEE ALSO
  498. *       animation.datatype,
  499. *       anim.datatype,
  500. *       mpegsystem.datatype, mpegvideo.datatype,
  501. *       picmovie.datatype,
  502. *       cdxl.datatype, avi.datatype, quicktime.datatype,
  503. *       moviesetter.datatype,
  504. *       film.datatype,
  505. *       directory.datatype,
  506. *       markabletextdtclass
  507. *
  508. *******************************************************************************
  509. *
  510. */
  511.  
  512.  
  513. /****** gifanim.datatype/--input_format-- ************************************
  514. *
  515. *    NAME
  516. *        GIF ANIM -- GIF Animation format
  517. *
  518. *    DESCRIPTION
  519. *        <Not written yet, sorry>
  520. *
  521. *    SEE ALSO
  522. *        gif.doc, gif89a.doc, compress.gif
  523. *
  524. *******************************************************************************
  525. *
  526. */
  527.  
  528.  
  529.  
  530. /*****************************************************************************/
  531.  
  532. DISPATCHERFLAGS
  533. struct IClass *ObtainGIFAnimEngine( REGA6 struct ClassBase *cb )
  534. {
  535.     return( (cb -> cb_Lib . cl_Class) );
  536. }
  537.  
  538. /*****************************************************************************/
  539.  
  540. DISPATCHERFLAGS
  541. struct Library *LibInit( REGD0 struct ClassBase *cb, REGA0 BPTR seglist, REGA6 struct ExecBase *sysbase )
  542. {
  543.     cb -> cb_SegList = seglist;
  544.     cb -> cb_SysBase = sysbase;
  545.  
  546.     InitSemaphore( (&(cb -> cb_Lock)) );
  547.  
  548.     /* Kickstart V3.0 ? */
  549.     if( (cb -> cb_SysBase -> LibNode . lib_Version) >= 39UL )
  550.     {
  551.       /* Obtain ROM libs */
  552.       if( cb -> cb_UtilityBase = OpenLibrary( "utility.library", 39UL ) )
  553.       {
  554.         if( cb -> cb_DOSBase = OpenLibrary( "dos.library", 39UL ) )
  555.         {
  556.           if( cb -> cb_GfxBase = OpenLibrary( "graphics.library", 39UL ) )
  557.           {
  558.             cb -> cb_CyberGfxBase = OpenLibrary( CYBERGFXNAME, CYBERGFXVERSION );
  559.  
  560.             if( cb -> cb_IntuitionBase = OpenLibrary( "intuition.library", 39UL ) )
  561.             {
  562.               return( (&(cb -> cb_Lib . cl_Lib)) );
  563.  
  564. #ifdef COMMENTED_OUT
  565.               CloseLibrary( (cb -> cb_IntuitionBase) );
  566. #endif /* COMMENTED_OUT */
  567.             }
  568.  
  569.             CloseLibrary( (cb -> cb_CyberGfxBase) );
  570.             CloseLibrary( (cb -> cb_GfxBase) );
  571.           }
  572.  
  573.           CloseLibrary( (cb -> cb_DOSBase) );
  574.         }
  575.  
  576.         CloseLibrary( (cb -> cb_UtilityBase) );
  577.       }
  578.     }
  579.  
  580.     return( NULL );
  581. }
  582.  
  583. /*****************************************************************************/
  584.  
  585. DISPATCHERFLAGS
  586. LONG LibOpen( REGA6 struct ClassBase *cb )
  587. {
  588.     LONG retval = (LONG)cb;
  589.     BOOL success = TRUE;
  590.  
  591.     ObtainSemaphore( (&(cb -> cb_Lock)) );
  592.  
  593.     /* Use an internal use counter */
  594.     cb -> cb_Lib . cl_Lib . lib_OpenCnt++;
  595.     cb -> cb_Lib . cl_Lib . lib_Flags &= ~LIBF_DELEXP;
  596.  
  597.     if( (cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 1U )
  598.     {
  599.       if( (cb -> cb_Lib . cl_Class) == NULL )
  600.       {
  601.         success = FALSE;
  602.  
  603.         if( cb -> cb_DataTypesBase = OpenLibrary( "datatypes.library", 39UL ) )
  604.         {
  605.           if( cb -> cb_SuperClassBase = OpenLibrary( "datatypes/animation.datatype", 41UL ) )
  606.           {
  607.             if( cb -> cb_Lib . cl_Class = initClass( cb ) )
  608.             {
  609.               success = TRUE;
  610.             }
  611.           }
  612.         }
  613.       }
  614.     }
  615.  
  616.     if( !success )
  617.     {
  618.       CloseLibrary( (cb -> cb_SuperClassBase) );
  619.       CloseLibrary( (cb -> cb_DataTypesBase) );
  620.  
  621.       cb -> cb_DataTypesBase = cb -> cb_SuperClassBase = NULL;
  622.  
  623.       (cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
  624.  
  625.       retval = 0L;
  626.     }
  627.  
  628.     ReleaseSemaphore( (&(cb -> cb_Lock)) );
  629.  
  630.     return( retval );
  631. }
  632.  
  633. /*****************************************************************************/
  634.  
  635. DISPATCHERFLAGS
  636. LONG LibClose( REGA6 struct ClassBase *cb )
  637. {
  638.     LONG retval = 0L;
  639.  
  640.     ObtainSemaphore( (&(cb -> cb_Lock)) );
  641.  
  642.     if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
  643.     {
  644.       (cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
  645.     }
  646.  
  647.     if( ((cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 0U) && (cb -> cb_Lib . cl_Class) )
  648.     {
  649.       if( FreeClass( (cb -> cb_Lib . cl_Class) ) )
  650.       {
  651.         cb -> cb_Lib . cl_Class = NULL;
  652.  
  653.         CloseLibrary( (cb -> cb_SuperClassBase) );
  654.         CloseLibrary( (cb -> cb_DataTypesBase) );
  655.       }
  656.       else
  657.       {
  658.         cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
  659.       }
  660.     }
  661.  
  662.     ReleaseSemaphore( (&(cb -> cb_Lock)) );
  663.  
  664.     if( (cb -> cb_Lib . cl_Lib . lib_Flags) & LIBF_DELEXP )
  665.     {
  666.       retval = LibExpunge( cb );
  667.     }
  668.  
  669.     return( retval );
  670. }
  671.  
  672. /*****************************************************************************/
  673.  
  674. DISPATCHERFLAGS
  675. LONG LibExpunge( REGA6 struct ClassBase *cb )
  676. {
  677.     BPTR seg;
  678.  
  679.     if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
  680.     {
  681.       cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
  682.  
  683.       seg = NULL;
  684.     }
  685.     else
  686.     {
  687.       Remove( (&(cb -> cb_Lib . cl_Lib . lib_Node)) );
  688.  
  689.       seg = cb -> cb_SegList;
  690.  
  691.       CloseLibrary( (cb -> cb_IntuitionBase) );
  692.       CloseLibrary( (cb -> cb_CyberGfxBase) );
  693.       CloseLibrary( (cb -> cb_GfxBase) );
  694.       CloseLibrary( (cb -> cb_DOSBase) );
  695.       CloseLibrary( (cb -> cb_UtilityBase) );
  696.  
  697.       FreeMem( (APTR)((ULONG)(cb) - (ULONG)(cb -> cb_Lib . cl_Lib . lib_NegSize)), (ULONG)((cb -> cb_Lib . cl_Lib . lib_NegSize) + (cb -> cb_Lib . cl_Lib . lib_PosSize)) );
  698.     }
  699.  
  700.     return( (LONG)seg );
  701. }
  702.  
  703.  
  704.